package org.maiyoframework.core.web.page;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

/**
 * 分类控件，最重要的分页类
 * 
 * @author maiYo
 * 
 * @param <T>
 */
public class Pagination<T> {

	/** 默认每页显示记录数 */
	public static final int DEF_PAGE_SIZE = 10;
	/** 前台页面显示页码数量，[1][2][3]... */
	public static final int DEF_PAGE_COUNT = 9;
	
	/** 查询记录总数 */
	private Long totalCount;
	/** 当前浏览页码 */
	private Integer pageNo;
	/** 每页显示记录数 */
	private Integer pageSize;

	public Pagination() {
	}

	/**
	 * 构造与处理分页参数
	 * 
	 * @param pageNo
	 *            当前浏览页码
	 * @param pageSize
	 *            每页显示记录数，设-1为系统默认值 DEF_PAGE_SIZE
	 * @author maiYo
	 */
	public Pagination(Integer pageNo, Integer pageSize) {
		setPageNo(pageNo);
		setPageSize(pageSize);
	}

	/** 获得开始记录索引 ，通过当前页号计算 */
	public int getStartIndex() {
		int startIndex = (pageNo - 1) * pageSize;
		return startIndex;
	}

	/** 获得总页数 */
	public int getTotalPage() {
		int result = (int) (totalCount / pageSize);
		return (totalCount % pageSize == 0) ? result : result + 1;
	}

	/** 获得上页的页号 */
	public int getPrePage() {
		return pageNo - 1 < 1 ? 1 : pageNo - 1;
	}

	/** 获得下页的页号 */
	public int getNextPage() {
		return pageNo + 1 > getTotalPage() ? getTotalPage() : pageNo + 1;
	}

	/**
	 * 封装返回给前台的分页类
	 * 
	 * @param pageResult
	 *            查询记录结果
	 * @param pageNo
	 *            当前浏览页码
	 * @param req
	 *            request请求对象
	 * @param pageCount
	 *            前台页面显示页码数量
	 * @return
	 * @author maiYo
	 */
	public Page<T> setPage(PageResult<T> pageResult, Integer pageNo,
			HttpServletRequest req, Map<String, String> urlParams, int pageCount) {
		// 获取记录总数
		setTotalCount(pageResult.getTotalCount());
		// 获得总页数
		int totalPage = getTotalPage();
		// 获得前台页面显示页码起始位置
		Page<T> page = getPageIndex(pageCount, pageNo, totalPage);
		// 封装记录集
		page.setRecordList(pageResult.getResultList());
		// 封装总页数
		page.setTotalPage(totalPage);
		// 封装总记录数
		page.setTotalCount(getTotalCount());
		// 封装页码样式
		page.setPaging(defalutSytlePaging(page, urlParams, req));
		return page;
	}

	/**
	 * 获得前台页面显示页码起始位置
	 * 
	 * @param pageCount
	 *            前台页面显示页码数量，设-1为系统默认值 DEF_PAGE_COUNT
	 * @param pageNo
	 *            当前浏览页码
	 * @param totalPage
	 *            记录总页数
	 * @return 前台页面分页页码的起始
	 * @author maiYo
	 */
	public Page<T> getPageIndex(int pageCount, Integer pageNo, int totalPage) {
		pageCount = (pageCount < 0) ? DEF_PAGE_COUNT : pageCount;
		int startPage = pageNo
				- (pageCount % 2 == 0 ? pageCount / 2 - 1 : pageCount / 2);
		int endPage = pageNo + pageCount / 2;
		if (startPage < 1) {
			startPage = 1;
			if (totalPage >= pageCount)
				endPage = pageCount;
			else
				endPage = totalPage;
		}
		if (endPage > totalPage) {
			endPage = totalPage;
			if ((endPage - pageCount) > 0)
				startPage = endPage - pageCount + 1;
			else
				startPage = 1;
		}
		return new Page<T>(startPage, endPage);
	}

	/**
	 * 组装分页样式与跳转超链接（默认样式）
	 * 
	 * @param page
	 *            返回给前台的page对象
	 * @param req
	 *            request请求对象
	 * @return
	 * @author maiYo
	 */
	public String defalutSytlePaging(Page<T> page,
			Map<String, String> urlParams, HttpServletRequest req) {
		// 获取action路径
		String action = (req != null ? req.getRequestURI() : "");
		// 设置查询参数
		String queryStr = "?p=";
		String queryParams = "";
		if (urlParams != null && urlParams.size() > 0) {
			for (String k : urlParams.keySet()) {
				queryParams += "&" + k + "=" + urlParams.get(k);
			}
		}
		/** 组装页码 */
		StringBuilder sb = new StringBuilder();
		// 如果只有一页，则直接返回空字符串
		if (page.getTotalPage() == 0) {
			return sb.toString();
		}
		// 上一页
		sb.append("<a href=\"" + action + queryStr + getPrePage() + queryParams
				+ "\">上一页</a>");
		// 超过三页则显示第一页链接
		if (page.getStartpage() >= 3) {
			sb.append("<a href=\"" + action + queryStr + "1" + queryParams
					+ "\">1..</a>");
		}
		// 中间页
		for (int i = page.getStartpage(); i <= page.getEndPage(); i++) {
			if (pageNo == i) {
				sb.append("<span class=\"visited\">" + i + "</span>");
			} else {
				sb.append("<a href=\"" + action + queryStr + i + queryParams + "\">"
						+ i + "</a>");
			}
		}
		// 最后页小于总页数，则显示最后一页
		if (page.getEndPage() < page.getTotalPage()) {
			sb.append("<a href=\"" + action + queryStr + page.getTotalPage()
					+ queryParams + "\">.." + page.getTotalPage() + "</a>");
		}
		// 下一页
		sb.append("<a href=\"" + action + queryStr + getNextPage() + queryParams
				+ "\" class=\"next\">下一页</a>");
		return sb.toString();
	}

	public Long getTotalCount() {
		return totalCount;
	}

	public void setTotalCount(Long totalCount) {
		this.totalCount = (totalCount < 0) ? 0 : totalCount;
	}

	public Integer getPageNo() {
		return pageNo;
	}

	public void setPageNo(Integer pageNo) {
		if (pageNo == null || pageNo < 1) {
			this.pageNo = 1;
		} else {
			this.pageNo = pageNo;
		}
	}

	public Integer getPageSize() {
		return pageSize;
	}

	public void setPageSize(Integer pageSize) {
		if (pageSize == null || pageSize < 0) {
			this.pageSize = DEF_PAGE_SIZE;
		} else {
			this.pageSize = pageSize;
		}
	}
}
